package org.fullhappy.dao;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

public class DAO<T> {
	
	private static final Logger LOGGER = Logger.getLogger("org.fullhappy.dao.DAO");

	private Class<T> entityClass;

	public DAO(Class<T> entityClass) {
		this.entityClass = entityClass;
	}

	public T insert(T entity) throws Exception {
		EntityManager entityManager = EMF.get().createEntityManager();
		EntityTransaction txn = entityManager.getTransaction();
		txn.begin();
		try {
			entityManager.persist(entity);
			txn.commit();
			return entity;			
		}catch(Exception e) {
			LOGGER.log(Level.OFF, "Create Exception "+ e.getMessage());
			throw e;
		}finally {
			if (txn.isActive()) {
				txn.rollback();
			}
			entityManager.close();
		}

	}

	public T find(Object id) {		
		EntityManager entityManager = EMF.get().createEntityManager();
		T t= entityManager.find(entityClass, id);
		entityManager.close();
		return t;

	}

	public void update(T entity) throws Exception {
		EntityManager entityManager = EMF.get().createEntityManager();
		EntityTransaction txn = entityManager.getTransaction();
		txn.begin();
		try {
			entityManager.merge(entity);
			txn.commit();
		}catch(Exception e) {
			LOGGER.log(Level.OFF, "Edit Exception "+ e.getMessage());
			throw e;
		}finally {
			if (txn.isActive()) {
				txn.rollback();
			}
			entityManager.close();
		}
	}

	public void delete(T entity) throws Exception {
		EntityManager entityManager = EMF.get().createEntityManager();
		EntityTransaction txn = entityManager.getTransaction();
		txn.begin();
		try {
			entityManager.remove(entityManager.merge(entity));
			txn.commit();
		}catch(Exception e) {
			LOGGER.log(Level.OFF, "Delete Exception "+ e.getMessage());
			throw e;
		}finally {
			if (txn.isActive()) {
				txn.rollback();
			}
			entityManager.close();
		}
	}

	public List<T> findAll() {
		EntityManager entityManager = EMF.get().createEntityManager();
		List<T> list1 = null;
		try {
			List<T> list = entityManager.createQuery(
					" SELECT e FROM " + entityClass.getSimpleName() + " e ")
					.getResultList();
			list1 = list.subList(0, list.size());
		} catch (Exception e) {
			Logger.getLogger("findAll" + e.getMessage());
		} finally {
			entityManager.close();
		}
		return list1;
	}
	
	public List<T> search(long from, long numerItem) {
		EntityManager entityManager = EMF.get().createEntityManager();
		List<T> list1 = null;
		try {
			List<T> list = entityManager.createQuery(
					" SELECT e FROM " + entityClass.getSimpleName() + " e LIMIT("+from+","+numerItem+") ")
					.getResultList();
			list1 = list.subList(0, list.size());
		} catch (Exception e) {
			Logger.getLogger("findAll" + e.getMessage());
		} finally {
			entityManager.close();
		}
		return list1;
	}
}
